<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
/**
 * Prunus OFC
 *
 * Wrapper para usar en prunus el OpenFlashChart
 *
 * @author		agosto
 * @date		  20090612
 * @version		0.1
 * @copyright	Copyright (c) 2009, 7dedos
 * @link		http://www.7dedos.com.ar
 */
 
 
 /*
  * Flujo de invocacion de metodos
  *
  *   Chart con datos embebidos en la pagina
  *
  *     - Config. Opcional. General para todos los charts.
  *     - Create. Individualmente por cada chart.
  *     - ProcessDataRow. Individualmente por chart y registro.
  *     - Compute. Individualmente por chart.
  *     - [crear un div con el id del chart para que se llene via javascript y crear opcionalmente un renderActions]
  *     - Render. General para todos los charts
  *
  *
  *   Chart con datos externos (similar ajax)
  *     EN LA VISTA:
  *     - Config. Opcional. General para todos los charts.
  *     - createExternalReference. Individualmente por cada chart.
  *     - [crear un div con el id del chart para que se llene via javascript y crear opcionalmente un renderActions]
  *     - Render. General para todos los charts
  *
  *     EN EL CONTROLADOR EXTERNO:
  *     - createExternal. Individualmente por cada chart.
  *     - ProcessDataRow. Individualmente por chart y registro.
  *     - Compute. Individualmente por chart.
  *     - renderExternal. Individualmente por chart.
  *
  */ 
class prunus_ofc
{
	protected $ci;
  protected $buffer;
  protected $offsetPosition;
  protected $defaultChartWidth;
  protected $defaultChartHeight;
  protected $flashVersion;
  protected $charts;
  protected $loadingLabel;
  protected $defaultColours;
  protected $backgroundColor;
  protected $dotColor;
  protected $xAxisColor;
  protected $yAxisColor;
  protected $xAxisLabelColor;
  protected $yAxisLabelColor;
  protected $gridVerticalLinesColor;
  protected $gridHorizontalLinesColor;
  protected $xAxisSteps;
  protected $xAxisLabelSteps;
  protected $xAxisLabelAngle;
  protected $toolTipShadow;
  protected $toolTipStroke;
  protected $toolTipColor;
  protected $toolTipFondo;
  protected $toolTipTitleStyle;
  protected $toolTipBodyStyle;
  protected $toolTipFormat;
  protected $xLegendStyle;
  protected $yLegendStyle;
  protected $titleStyle;
    
	public function __construct()	{
		$this->ci =& get_instance();
    $this->ci->load->config('prunus_ofc');
    $this->offsetPosition = $this->ci->config->item('PROFC_defaultOffset');
    $this->defaultChartWidth = $this->ci->config->item('PROFC_defaultWidth');
    $this->defaultChartHeight = $this->ci->config->item('PROFC_defaultHeight');
    $this->flashVersion = $this->ci->config->item('PROFC_defaultFlashVersion');
    $this->defaultColours = $this->ci->config->item('PROFC_defaultColours');
    
    //look and feel    
    $this->backgroundColor = $this->ci->config->item('PROFC_defaultChartBackgroundColor');
    $this->dotColor = $this->ci->config->item('PROFC_defaultDotColor');
    $this->xAxisColor = $this->ci->config->item('PROFC_defaultXAxisColor');
    $this->yAxisColor = $this->ci->config->item('PROFC_defaultYAxisColor');
    $this->xAxisLabelColor = $this->ci->config->item('PROFC_defaultXAxisLabelColor');
    $this->yAxisLabelColor = $this->ci->config->item('PROFC_defaultYAxisLabelColor');
    $this->gridVerticalLinesColor = $this->ci->config->item('PROFC_defaultGridVerticalLinesColor');
    $this->gridHorizontalLinesColor = $this->ci->config->item('PROFC_defaultGridHorizontalLinesColor');
    $this->xAxisSteps = $this->ci->config->item('PROFC_defaultXAxisSteps');
    $this->xAxisLabelSteps = $this->ci->config->item('PROFC_defaultXAxisLabelsSteps');
    $this->xAxisLabelAngle = $this->ci->config->item('PROFC_defaultXAxisLabelsAngle');
    $this->toolTipShadow = $this->ci->config->item('PROFC_defaultTooltipShadow');
    $this->toolTipStroke = $this->ci->config->item('PROFC_defaultTooltipStroke');
    $this->toolTipColor = $this->ci->config->item('PROFC_defaultTooltipColor');
    $this->toolTipFondo = $this->ci->config->item('PROFC_defaultTooltipFondo');
    $this->toolTipTitleStyle = $this->ci->config->item('PROFC_defaultTooltipTitleStyle');
    $this->toolTipBodyStyle = $this->ci->config->item('PROFC_defaultTooltipBodyStyle');
    $this->toolTipFormat = $this->ci->config->item('PROFC_defaultTooltip');
    $this->xLegendStyle = $this->ci->config->item('PROFC_xLegendStyle');
    $this->yLegendStyle = $this->ci->config->item('PROFC_yLegendStyle');
    $this->titleStyle = $this->ci->config->item('PROFC_titleStyle');
    
    $this->charts = array();
    include_once ('ofc/open-flash-chart.php');
    
    define("PROFC_glassBar", $this->ci->config->item('PROFC_chartTypeGlassBar'));
    define("PROFC_filledBar", $this->ci->config->item('PROFC_chartTypeFilledBar'));
    define("PROFC_lineHollow", $this->ci->config->item('PROFC_chartTypeLineHollow'));
    define("PROFC_area", $this->ci->config->item('PROFC_chartTypeArea'));
    define("PROFC_pie", $this->ci->config->item('PROFC_chartTypePie'));
    
		log_message('debug', 'prunus_ofc inicializado');
	}
	
  private function bufferClear() { $this->buffer = ''; }
  private function bufferAdd($position, $text) { $this->buffer .= $this->ci->prunus_core->gi ( ($this->offsetPosition + $position), $text); }
  
  public function config ($loadingLabel = '', $offset = -1) {
    if ($offset != -1) $this->$offsetPosition = $offset;
    $this->loadingLabel = $loadingLabel;
  } //config

  public function create ($id, $title, $width=0, $height=0, $chartType=PROFC_glassBar, $xLegend = "", $yLegend = "") {
    $this->charts[$id]['lastDefaultColours'] = 0;
    $this->charts[$id]['xAxis']['labels'] = array();
    $this->charts[$id]['xAxis']['values'] = array();
    $this->charts[$id]['data'] = array();
    $this->charts[$id]['chartType'] = $chartType;
    $this->charts[$id]['dataFile'] = '';
    if ($width != 0) { $this->charts[$id]['chartWidth'] = $width; } else { $this->charts[$id]['chartWidth'] = $this->defaultChartWidth; }
    if ($height != 0) { $this->charts[$id]['chartHeight'] = $height; } else { $this->charts[$id]['chartHeight'] = $this->defaultChartHeight; }
    $this->charts[$id]['chart'] = new open_flash_chart();
    $this->charts[$id]['title'] = $title;
    $this->charts[$id]['xLegend'] = $xLegend;
    $this->charts[$id]['yLegend'] = $yLegend;
  } //create
  
  public function createExternal($id, $title, $chartType=PROFC_glassBar, $xLegend = "", $yLegend = "") {
    $this->charts[$id]['lastDefaultColours'] = 0;
    $this->charts[$id]['xAxis']['labels'] = array();
    $this->charts[$id]['xAxis']['values'] = array();
    $this->charts[$id]['data'] = array();
    $this->charts[$id]['chartType'] = $chartType;
    $this->charts[$id]['dataFile'] = '';
    $this->charts[$id]['chart'] = new open_flash_chart();
    $this->charts[$id]['title'] = $title;
    $this->charts[$id]['xLegend'] = $xLegend;
    $this->charts[$id]['yLegend'] = $yLegend;
  } //createExternal

  public function createExternalReference ($id, $width=0, $height=0, $dataFile = '') {
    $this->charts[$id]['dataFile'] = $dataFile;
    if ($width != 0) { $this->charts[$id]['chartWidth'] = $width; } else { $this->charts[$id]['chartWidth'] = $this->defaultChartWidth; }
    if ($height != 0) { $this->charts[$id]['chartHeight'] = $height; } else { $this->charts[$id]['chartHeight'] = $this->defaultChartHeight; }
  } //createExternalReference
  
  public function processDataRow($id, $dataArray,$datasetDataField,$datasetLabelField,$valueField,$xAxisField,$xLabelField, $datasetColorField = null) {
    //cargo los valores en variables locales
    $dataset = $dataArray->{$datasetDataField};
    $datasetLabel = $dataArray->{$datasetLabelField};
    $value = (float)$dataArray->{$valueField};
    $xAxis = $dataArray->{$xAxisField};
    $xLabel = $dataArray->{$xLabelField};
    $color = ''; if ($datasetColorField !== null) $color = $dataArray->{$datasetColorField};
    
    //si es un nuevo x-label, lo agrego al array
    if (! in_array($xAxis, $this->charts[$id]['xAxis']['values'])) { 
      $this->charts[$id]['xAxis']['values'][] = $xAxis; 
      $this->charts[$id]['xAxis']['labels'][] = $xLabel; 
    }
    
    
    if (array_key_exists($dataset,$this->charts[$id]['data'])) { //si ya hay datos para esta serie, agrego el valor
      //agrego ceros si en los dataset anteriores no habia datos
      for ($i=count($this->charts[$id]['data'][$dataset]['values']); $i<(count($this->charts[$id]['xAxis']['values'])-1); $i++) $this->charts[$id]['data'][$dataset]['values'][] = 0;
      $this->charts[$id]['data'][$dataset]['values'][] = $value;
    } else {
      //creo los valores para la nueva serie
      $values = array();
      for ($i=0; $i<(count($this->charts[$id]['xAxis']['values'])-1); $i++) $values[] = 0;
      $values[] = $value;
      
      $this->charts[$id]['data'][$dataset] = array('id' => $dataset,'label' => $datasetLabel,'values' => $values,'color' => $color);
    }
  } //processDataRow
  
  public function compute($id) {
    if ($this->charts[$id]['chartType'] != PROFC_pie) {
      foreach ($this->charts[$id]['data'] as $item) {
        for ($i=count($item['values']); $i < count($this->charts[$id]['xAxis']['values']); $i++) $item['values'][]=0; //relleno con 0 al final
        
        switch($this->charts[$id]['chartType']) {
          case PROFC_filledBar: 
            $element = new bar_filled(); 
            $element->set_values($item['values']);
            $element->key($item['label'], 12);
            $element->set_on_show(new bar_on_show('grow-up', 1, 0));
            if ($item['color'] == '') { $element->colour($this->defaultColours[$this->charts[$id]['lastDefaultColours']++]); } else { $element->colour($item['color']); }
            break;
          case PROFC_lineHollow: 
            $d = new hollow_dot();
            $d->size(4)->halo_size(1)->colour($this->dotColor);
            $d->tooltip(str_replace("#label#", $item['label'], $this->toolTipFormat));
            $element = new line(); 
            $element->set_values($item['values']);
            $element->set_text($item['label'], 12);
            $element->set_default_dot_style($d);
            $element->set_on_show(new line_on_show('drop', 1, 0));
            $element->set_width(2);
            if ($item['color'] == '') { $element->set_colour($this->defaultColours[$this->charts[$id]['lastDefaultColours']++]); } else { $element->set_colour($item['color']); }
            break;
          case PROFC_area: 
            $d = new hollow_dot();
            $d->size(4)->halo_size(1)->colour($this->dotColor);

            $element = new area();
            // set the circle line width:
            $element->set_width( 2 );
            $element->set_default_dot_style($d);
            $element->set_text($item['label'], 12);
            if ($item['color'] == '') { $element->set_colour($this->defaultColours[$this->charts[$id]['lastDefaultColours']++]); } else { $element->set_colour($item['color']); }
            if ($item['color'] == '') { $element->set_fill_colour($this->defaultColours[$this->charts[$id]['lastDefaultColours']++]); } else { $element->set_fill_colour($item['color']); }
            $element->set_fill_alpha( 0.7 );
            $element->set_values($item['values']);
            break;
          default: 
            $element = new bar_glass(); 
            $element->set_values($item['values']);
            $element->set_tooltip(str_replace("#label#", $item['label'], $this->toolTipFormat));
            $element->key($item['label'], 12);
            $element->set_on_show(new bar_on_show('grow-up', 1, 0));
            if ($item['color'] == '') { $element->colour($this->defaultColours[$this->charts[$id]['lastDefaultColours']++]); } else { $element->colour($item['color']); }
        } 
        $this->charts[$id]['chart']->add_element($element);
      }
      
            

      $xlabels = new x_axis_labels();
      $xlabels->set_steps($this->xAxisLabelSteps);
      $xlabels->rotate($this->xAxisLabelAngle);
      $xlabels->set_colour($this->xAxisLabelColor);
      $xlabels->set_labels( $this->charts[$id]['xAxis']['labels'] );
      $x = new x_axis();
      $x->set_colour($this->xAxisColor);
      $x->set_grid_colour($this->gridVerticalLinesColor);
      $x->set_steps($this->xAxisSteps);
      $x->set_labels($xlabels);
      $this->charts[$id]['chart']->set_x_axis( $x );    
      
      $ylabels = new y_axis_labels();
      $ylabels->set_colour($this->yAxisLabelColor);
      $y = new y_axis();
      $y->set_colour($this->yAxisColor);
      $y->set_grid_colour($this->gridHorizontalLinesColor);
      $y->set_labels($ylabels);
      $this->charts[$id]['chart']->set_y_axis( $y );

      $this->charts[$id]['chart']->set_bg_colour($this->backgroundColor);  
      
      $t = new tooltip();
      $t->set_shadow($this->toolTipShadow);
      $t->set_stroke($this->toolTipStroke);
      $t->set_colour($this->toolTipColor);
      $t->set_background_colour($this->toolTipFondo);
      $t->set_title_style($this->toolTipTitleStyle);
      $t->set_body_style($this->toolTipBodyStyle);
      $this->charts[$id]['chart']->set_tooltip( $t );
      
      if ($this->charts[$id]['xLegend'] != "") {
        $x_legend = new x_legend($this->charts[$id]['xLegend']);
        $x_legend->set_style($this->xLegendStyle);
        $this->charts[$id]['chart']->set_x_legend($x_legend);
      }

      if ($this->charts[$id]['yLegend'] != "") {
        $y_legend = new y_legend($this->charts[$id]['yLegend']);
        $y_legend->set_style($this->yLegendStyle);
        $this->charts[$id]['chart']->set_y_legend( $y_legend );
      }

      if ($this->charts[$id]['title'] != "") {
        $title = new title($this->charts[$id]['title']);
        $title->set_style($this->titleStyle);
        $this->charts[$id]['chart']->set_title($title);
      }
      
    } else {
      //pie chart. solo se usa el primer elemento de $this->charts[$id]['data']
      $colores = array();
      for ($i=0; $i<count($this->charts[$id]['data'][1]['values']); $i++) $colores[] = $this->defaultColours[$this->charts[$id]['lastDefaultColours']++];
      $valores = array();
      for ($i=0; $i<count($this->charts[$id]['data'][1]['values']); $i++) $valores[] = new pie_value($this->charts[$id]['data'][1]['values'][$i],$this->xLabels[$i]);
      
      $element = new pie();
      $element->set_alpha(0.6);
      $element->set_start_angle( 35 );
      $element->add_animation( new pie_fade() );
      $element->set_tooltip( '#val# of #total#<br>#percent# of 100%' );
      $element->set_colours( $colores );
      $element->set_values($valores);
      $this->chart->add_element($element);
    }
  } //compute

  public function render() {
    $this->bufferClear();
    $this->bufferAdd(0, "<script type=\"text/javascript\">");
    $this->bufferAdd(0, "//<![CDATA[");
    foreach ($this->charts as $id => $chart) {
      if ($chart['dataFile'] !== '') { $dataFile = ", \"data-file\":\"" . $chart['dataFile'] . "\""; } else { $dataFile = ''; }
      if ($this->loadingLabel != '') {
        $this->bufferAdd(2, "swfobject.embedSWF(\"" . base_url() . "flash/open-flash-chart.swf\", \"" . $id . "\", \"" . $chart['chartWidth'] . "\", \"" . $chart['chartHeight'] . "\", \"" . $this->flashVersion . "\", \"expressInstall.swf\", {\"get-data\":\"get_data_" . $id . "\", \"id\":\"" . $id . "\", \"loading\":\"" . $this->loadingLabel . "\"" . $dataFile . "} );");
      } else {
        $this->bufferAdd(2, "swfobject.embedSWF(\"" . base_url() . "flash/open-flash-chart.swf\", \"" . $id . "\", \"" . $chart['chartWidth'] . "\", \"" . $chart['chartHeight'] . "\", \"" . $this->flashVersion . "\", \"expressInstall.swf\", {\"get-data\":\"get_data_" . $id . "\", \"id\":\"" . $id . "\"" . $dataFile . "} );");
      }
    }
    $this->bufferAdd(2, "function ofc_ready(id) {  }");
    $this->bufferAdd(2, "function ofc_resize(left, width, top, height, id) { }");
    $this->bufferAdd(2, "function findSWF(movieName) { if (navigator.appName.indexOf(\"Microsoft\")!= -1) { return window[movieName]; } else { return document[movieName]; } }");
    
    $code = "";
    foreach ($this->charts as $id => $chart) {
      $code .= "$(\"#" . $id . "\").css('width', 0); x=$(\"#" . $id . "\").parent().css('width'); $(\"#" . $id . "\").parent().children().css('width', x);";
    }
    $this->bufferAdd(2, "$(window).load(function() {");
    $this->bufferAdd(4, $code);
    $this->bufferAdd(2, "});");
    $this->bufferAdd(2, "$(window).resize(function () {");
    $this->bufferAdd(4, $code);
    $this->bufferAdd(2, "});");
    
    foreach ($this->charts as $id => $chart) {
      if ($chart['dataFile'] === '') {
        $this->bufferAdd(2, "function get_data_" . $id . "() {");
        $this->bufferAdd(4, "return JSON.stringify(data_" . $id . ");");
        $this->bufferAdd(2, "}");
      }
    }

    foreach ($this->charts as $id => $chart) {
      if ($chart['dataFile'] === '') {
        $this->bufferAdd(2, "var data_" . $id . " = " . $chart['chart']->toPrettyString() . ";");
      }
    }
    
    $this->bufferAdd(0, "//]]>");
    $this->bufferAdd(0, "</script>");
    
    return $this->buffer;
  } //render
  
  public function renderContainerDiv($id) {
    $this->bufferClear();
    $this->bufferAdd(0, "<div id=\"" . $id . "\">");
    $this->bufferAdd(0, "</div>");
    return $this->buffer;
  }
  
  public function renderActions($id) {
    $this->bufferClear();
    foreach ($this->charts as $chartId => $chart) {
      if ($chartId == $id) {
        if ($chart['dataFile'] !== '') {
          $this->bufferAdd(0, "<a href='#' onclick=\" tmp = findSWF('" . $id . "'); tmp.reload('" . $chart['dataFile'] . "');\"><span class=\"PROFC_action PROFC_action_reload\">&nbsp;</span></a>");
        }
      }
    }
    return $this->buffer;
  }
  public function renderExternal($id) {
    foreach ($this->charts as $chartId => $chart) {
      if ($chartId == $id) {
        return ($chart['chart']->toPrettyString());
      }
    }
  }
}
